﻿
namespace TFSChangeLog.Operations.Services
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Threading;
    using Microsoft.TeamFoundation.VersionControl.Client;
    using TFSChangeLog.ViewModel;

    /// <summary>Summary description for <see cref="SelectBranchNodeService"/> class.</summary>
    public static class SelectBranchNodeService
    {
        /// <summary>Summary description for <c>SelectBranchNodeService</c> method.</summary>
        /// <param name="singleIterationList">TODO: Summary description for <c>singleIterationList</c> parameter of type <c>int[]</c>.</param>
        /// <param name="m_ViewModel">TODO: Summary description for <c>m_ViewModel</c> parameter of type <c>TFSChangeLog.ViewModel.MainWindowViewModel</c>.</param>
        public static void DoWork(int[] singleIterationList, MainWindowViewModel m_ViewModel)
        {
            // Get a cancellation token
            var loopOptions = new ParallelOptions();
            loopOptions.CancellationToken = m_ViewModel.progressDialogViewModel.TokenSource.Token;
            try
            {
                Parallel.ForEach(singleIterationList, loopOptions, t => GetChangeSetInformation(m_ViewModel));
            }
            catch (OperationCanceledException)
            {
                var ShowCancellationMessage = new Action(m_ViewModel.progressDialogViewModel.ShowCancellationMessage);
                Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, ShowCancellationMessage);
            }
            catch (Exception e)
            {
                var ShowCancellationMessage = new Action(m_ViewModel.progressDialogViewModel.ShowCancellationMessage);
                Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, ShowCancellationMessage);
            }
        }

        /// <summary>Summary description for <c>SelectBranchNodeService</c> method.</summary>
        /// <param name="m_ViewModel">TODO: Summary description for <c>m_ViewModel</c> parameter of type <c>TFSChangeLog.ViewModel.MainWindowViewModel</c>.</param>
        public static void GetChangeSetInformation(MainWindowViewModel m_ViewModel)
        {
            GetSelectedBranch(m_ViewModel);

            ProgressDialogViewModel viewModel = m_ViewModel.progressDialogViewModel;
            if (TFSChangeLog.DataAccess.TFSChangeLogStaticConfigs.IsRunningFromCommandPrompt == false)
                {
                SetProgressBarMessage(viewModel);
                }

            if (m_ViewModel.TFSProjectSelectedBranchName != string.Empty || m_ViewModel.TFSProjectSelectedBranchName != "ROOTPLACEHOLDER")
            {
                if (m_ViewModel.progressDialogViewModel.TokenSource.Token.IsCancellationRequested)
                    {
                        return;
                    }

                List<Changeset> TempFromchangeSets = TFSChangeLog.DataAccess.ChangeSetDataAccess.GetChangesets(m_ViewModel.TFSProjectSelectedBranchName);
                if (m_ViewModel.progressDialogViewModel.TokenSource.Token.IsCancellationRequested)
                    {
                        return;
                    }

                List<Changeset> tempTochangeSets = TFSChangeLog.DataAccess.ChangeSetDataAccess.GetChangesets(m_ViewModel.TFSProjectSelectedBranchName);
                if (m_ViewModel.progressDialogViewModel.TokenSource.Token.IsCancellationRequested)
                    {
                        return;
                    }

                if (m_ViewModel.FromChangeSets == null)
                {
                    m_ViewModel.FromChangeSets = new ObservableCollection<FromChangeSetViewModel>();
                }

                if (TFSChangeLog.DataAccess.TFSChangeLogStaticConfigs.IsRunningFromCommandPrompt == false)
                {
                    var ClearFromChangeSetsListBox = new Action(m_ViewModel.FromChangeSets.Clear);
                    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, ClearFromChangeSetsListBox);
                }
                else
                {
                    m_ViewModel.FromChangeSets.Clear();
                }

                if (TempFromchangeSets != null)
                {
                    foreach (var tempFromchangeSet in TempFromchangeSets)
                    {
                        if (TFSChangeLog.DataAccess.TFSChangeLogStaticConfigs.IsRunningFromCommandPrompt == false)
                        {
                            Application.Current.Dispatcher.Invoke(
                                                                  DispatcherPriority.Normal,
                                                                  new Action<FromChangeSetViewModel>(
                                                                      m_ViewModel.FromChangeSets.Add),
                                                                  new FromChangeSetViewModel(tempFromchangeSet));
                        }
                        else
                        {
                            m_ViewModel.FromChangeSets.Add(new FromChangeSetViewModel(tempFromchangeSet));
                        }
                    }
                }

                // Select oldest change set from the FromChangeSet ObservableCollection
                // and then refresh the GUI by raising OnPropertyChange event.
                if (m_ViewModel.FromChangeSets != null && m_ViewModel.FromChangeSets.Count > 0)
                {
                    m_ViewModel.FromChangeSets[m_ViewModel.FromChangeSets.Count - 1].IsSelected = true;
                    m_ViewModel.OnPropertyChanged("FromChangeSets");

                    // base.OnPropertyChanged("FromChangeSets");
                    m_ViewModel.SelectedFromChangeSet = m_ViewModel.FromChangeSets[m_ViewModel.FromChangeSets.Count - 1];
                }

                if (m_ViewModel.ToChangeSets == null)
                {
                    m_ViewModel.ToChangeSets = new ObservableCollection<ToChangeSetViewModel>();
                }

                if (TFSChangeLog.DataAccess.TFSChangeLogStaticConfigs.IsRunningFromCommandPrompt == false)
                {
                    var ClearToChangeSetsListBox = new Action(m_ViewModel.ToChangeSets.Clear);
                    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, ClearToChangeSetsListBox);
                }
                else
                {
                    m_ViewModel.ToChangeSets.Clear();   
                }

                if (tempTochangeSets != null)
                {
                    foreach (var tempTochangeSet in tempTochangeSets)
                    {
                        if (TFSChangeLog.DataAccess.TFSChangeLogStaticConfigs.IsRunningFromCommandPrompt == false)
                        {
                            Application.Current.Dispatcher.Invoke(
                                                                  DispatcherPriority.Normal,
                                                                  new Action<ToChangeSetViewModel>(
                                                                      m_ViewModel.ToChangeSets.Add),
                                                                  new ToChangeSetViewModel(tempTochangeSet));
                        }
                        else
                        {
                            m_ViewModel.ToChangeSets.Add(new ToChangeSetViewModel(tempTochangeSet));
                        }
                    }
                }

                // Select newest change set from the ToChangeSet ObservableCollection
                // and then refresh the GUI by raising OnPropertyChange event.
                if (m_ViewModel.ToChangeSets != null && m_ViewModel.ToChangeSets.Count > 0)
                {
                    m_ViewModel.ToChangeSets[0].IsSelected = true;
                    m_ViewModel.OnPropertyChanged("ToChangeSets");
                    m_ViewModel.SelectedToChangeSet = m_ViewModel.ToChangeSets[0];
                }

                if (m_ViewModel.FromChangeSets.Count > 0 && m_ViewModel.ToChangeSets.Count > 0)
                {
                    m_ViewModel.CanExecuteGenerateReleaseNotes = true;
                    m_ViewModel.IsFromChangeSetsEnabled = true;
                    m_ViewModel.IsToChangeSetsEnabled = true;
                    m_ViewModel.IsTxtFileEnabled = true;
                    m_ViewModel.CanExecuteGenerateFileChanges = true;
                }
                else
                {
                    m_ViewModel.CanExecuteGenerateReleaseNotes = false;
                    m_ViewModel.IsFromChangeSetsEnabled = false;
                    m_ViewModel.IsToChangeSetsEnabled = false;
                    m_ViewModel.IsTxtFileEnabled = true;
                    m_ViewModel.CanExecuteGenerateFileChanges = false;
                }
            }
        }

        /// <summary>Summary description for <c>SelectBranchNodeService</c> method.</summary>
        /// <param name="m_ViewModel">TODO: Summary description for <c>m_ViewModel</c> parameter of type <c>TFSChangeLog.ViewModel.MainWindowViewModel</c>.</param>
        private static void GetSelectedBranch(MainWindowViewModel m_ViewModel)
        {
            m_ViewModel.TFSProjectSelectedBranchName = string.Empty;
            foreach (var childBranches in m_ViewModel.FirstGeneration)
            {
                if (childBranches.IsSelected)
                {
                    m_ViewModel.TFSProjectSelectedBranchName = childBranches.Name;
                    break;
                }

                if (childBranches.Children.Count > 0)
                {
                    GetSelectedBranch(m_ViewModel, childBranches.Children);
                }
            }
        }

        /// <summary>Summary description for <c>SelectBranchNodeService</c> method.</summary>
        /// <param name="m_ViewModel">TODO: Summary description for <c>m_ViewModel</c> parameter of type <c>TFSChangeLog.ViewModel.MainWindowViewModel</c>.</param>
        /// <param name="childBranchesCollection">TODO: Summary description for <c>childBranchesCollection</c> parameter of type <c>System.Collections.Generic.IEnumerable{TFSChangeLog.ViewModel.BranchViewModel}</c>.</param>
        private static void GetSelectedBranch(MainWindowViewModel m_ViewModel, IEnumerable<BranchViewModel> childBranchesCollection)
        {
            foreach (var childBranches in childBranchesCollection)
            {
                if (childBranches.IsSelected)
                {
                    m_ViewModel.TFSProjectSelectedBranchName = childBranches.Name;
                    break;
                }

                if (childBranches.Children.Count > 0)
                {
                    GetSelectedBranch(m_ViewModel, childBranches.Children);
                }
            }
        }

        /// <summary>
        ///  Set Progress Bar Message.
        /// </summary>
        /// <param name="viewModel">TODO: Summary description for <c>viewModel</c> parameter of type <c>TFSChangeLog.ViewModel.ProgressDialogViewModel</c>.</param>
        private static void SetProgressBarMessage(ProgressDialogViewModel viewModel)
        {
            string message = "Quering TFS for ChangeSet List";
            var SetProgressMessage = new Action<string>(viewModel.SetProgressMessage);
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, SetProgressMessage, message);
        }
    }
}
